#include "fileselector.h"
#include "ui_fileselector.h"
#include <QtGui>
#include "keybindings.h"
#include "messagedialog.h"
#include <QTest>

bool sortByName(MediaFile * file1, MediaFile * file2) {
    return file1->shortName.toLower()<file2->shortName.toLower();
}

bool sortByDate(MediaFile * file1, MediaFile * file2) {
    QFileInfo info1(file1->fileLocation+"/"+file1->shortName);
    QFileInfo info2(file2->fileLocation+"/"+file2->shortName);
    return info1.created()<info2.created();
}

FileSelector::FileSelector(QWidget *parent, FileSelectionInterface * interface) :
    KeyControllableMenu(parent),
    ui(new Ui::FileSelector)
{
    ui->setupUi(this);
    WindowManager::addWidget(this);
    //setMaximumSize(QApplication::desktop()->size());
    connect(this,SIGNAL(escapeTop()),this,SLOT(on_upButton_clicked()));
    connect(this,SIGNAL(escapeBottom()),this,SLOT(on_downButton_clicked()));
    setCircularVertically(false);
    ui->fileLayout->setMinimumWidth(QApplication::desktop()->screen(0)->width()/2-50);
    ui->descriptionLayout->setMinimumWidth(QApplication::desktop()->screen(0)->width()/2-50);
    //itemsPerPage=5;
    itemsPerPage=(QApplication::desktop()->screen(0)->height()-300)/90;
    sortByButton=new DropDownButton(QIcon(""),"Name",this);
    QVBoxLayout * sortLayout=new QVBoxLayout();
    sortLayout->setMargin(0);
    ui->searchBox->setStyleSheet("background-color: white; color: black");
    ui->sortByWidget->setLayout(sortLayout);
    ui->sortByWidget->layout()->addWidget(sortByButton);
    addRow(sortByButton);
    connect(sortByButton,SIGNAL(selected(Button *)),this,SLOT(buttonSelected(Button*)));
    nameSort=new Button(QIcon(""),"Name",this);
    sortByButton->addButton(nameSort);
    dateSort=new Button(QIcon(""),"Date Created",this);
    sortByButton->addButton(dateSort);
    setMouseTracking(true);
    layout()->setSpacing(10);
    current=0;
    filter="";
    QString unSelectedStyleSheet="background: rgba(255, 255, 255, 15); border: 1px solid rgba(255, 255, 255, 0); text-align: left; color: white;";
    QString selectedStyleSheet="background: qlineargradient(spread:pad, x1:0.07, y1:0.153409, x2:1, y2:1, stop:0 rgba(0, 0, 0, 50), stop:1 rgba(255, 255, 255, 70)); color: white; text-align: left; border: 1px solid rgba(255, 255, 255, 200);";
    QString inactiveSelectedStyleSheet="background: qlineargradient(spread:pad, x1:0.07, y1:0.153409, x2:1, y2:1, stop:0 rgba(255, 255, 255, 100), stop:1 rgba(255, 255, 255, 200)); color: white; text-align: left; border: 1px solid rgba(255, 255, 255, 200)";
    setStyleSheets(selectedStyleSheet,unSelectedStyleSheet, inactiveSelectedStyleSheet);
    this->interface=interface;
    ui->movieName->setWordWrap(true);
    ui->movieName->setStyleSheet("color:white");
    ui->textDescription->setStyleSheet("color:white");
    ui->textDescription->setWordWrap(true);
    filteredFiles=new QList<MediaFile *>();
    checker=new MediaChecker();
    reloadFiles();
    playerLayout=new QVBoxLayout();
    player=interface->getInterface();

    popup=new PopupMenu(this);
    connect(popup,SIGNAL(selected(Button*)),this,SLOT(buttonSelected(Button*)));

    favouriteButton=new Button(QIcon(""),"Add to favourites",popup);
    popup->addButton(favouriteButton);

    // cannot show up when viewing a playlist
    addToPlaylistButton=new Button(QIcon(""),"Add to playlist",popup);
    popup->addButton(addToPlaylistButton);

    // Must show up when viewing a playlist
    removeFromPlaylistButton=new Button(QIcon(""),"Remove from playlist",popup);
    popup->addButton(removeFromPlaylistButton);

    propertiesButton=new Button(QIcon(""),"Properties",popup);
    popup->addButton(propertiesButton);

    if(interface->getName() != "Photos") // cover art is not for photos (they use previews)
    {
        coverArtButton=new Button(QIcon(""),"Change cover art",popup);
        popup->addButton(coverArtButton);
    }

    cancelButton=new Button(QIcon(""),"Cancel",popup);
    popup->addButton(cancelButton);

    popup->hide();

    propertiesDialog = new PropertiesDialog(this);
    connect(propertiesDialog,SIGNAL(closed(MediaFile *)),this,SLOT(propertiesModified(MediaFile *)));
    propertiesDialog->hide();
    playlistSelectionDialog = new PlaylistSelectionDialog(this);
    connect(playlistSelectionDialog,SIGNAL(closed(QString *)),this,SLOT(addCurrentMediaToPlaylist(QString *)));
    playlistSelectionDialog->hide();

}

FileSelector::~FileSelector()
{
    delete ui;
}

void FileSelector::reloadFiles(QString playlistName) {
    ui->movieName->setText("");
    ui->textDescription->setText("");
    ui->thumbnail->setPixmap(QPixmap());
    //ui->filesLayout->children().removeAll();
    ui->upButton->hide();
    ui->downButton->hide();
    this->playlistName = playlistName;

    try {
        qDebug() <<interface->getName();
        files=Querier::getFilesOfType(interface->getName(),filter);
    }
    catch(char * error) {
        qDebug() <<error;
    }

    qSort(files->begin(),files->end(),sortByName);
    filteredFiles->clear();
    foreach(MediaFile * file, * files) {
        if(file->shortName.contains(ui->searchBox->text())) {
            filteredFiles->append(file);
        }
    }

    if(filteredFiles->size()>itemsPerPage) {
        ui->downButton->show();
    }
    showFiles(0);
}

void FileSelector::showFiles(int startIndex) {
    if(startIndex<0||(startIndex>=filteredFiles->size()&&filteredFiles->size()>0)) {
        return;
    }
   foreach( QObject * object,ui->fileLayout->children() ) {

        Button * button=qobject_cast<Button *>(object);
        if(button) {
            removeButton(button);
            delete button;
        }
    }
    if(interface->getName()!="Photos") {
       foreach(MediaFile * file, * files) {
           if(file->description.size()==0) {
               checker->checkValid(file);
           }
       }
    }
    buttons=new QList<Button *>();
    for(int i=startIndex; i<startIndex+itemsPerPage&&i<filteredFiles->count(); i++) {
        MediaFile * file=filteredFiles->at(i);
        Button * button=new Button(this->interface->getIcon(file), file->shortName.mid(0,file->shortName.lastIndexOf(".")), this, file);
        button->setIconSize(QSize(64,64));
        button->setFont(QFont("Times New Roman", 25,1,false));

        button->setMinimumHeight(70);
        button->setMinimumWidth(500);
        button->setMinimumSize(500,70);
        button->setMaximumSize(500,70);
        buttons->append(button);
        ui->files->addWidget(button,0,Qt::AlignTop);
        QList<Button *> * row=new QList<Button *>();
        row->append(button);
        addRow(row);
    }
    if(buttons->size()>0) {
        setActive(buttons->at(0));
        setCurrent(filteredFiles->indexOf((MediaFile *)buttons->at(0)->getItem()));
        removeButton(sortByButton);
        if(startIndex==0) {
            addButtonBefore(sortByButton,buttons->at(0));
        } else {
            addRow(sortByButton);
        }
    }

}

//Set filter for use in updating fileselector from database
void FileSelector::setFilter(QString filter) {
    this->filter=filter;
}

void FileSelector::buttonEntered(Button * button) {
    if(!active) {
        return;
    }
    KeyControllableMenu::buttonEntered(button);
    if(button!=sortByButton&&dynamic_cast<MediaFile *>(button->getItem())) {
        setCurrent(filteredFiles->indexOf(dynamic_cast<MediaFile *>(button->getItem())));
    }
}

void FileSelector::setCurrent(int current) {
    if(buttons->size()==0) {
        ui->downButton->hide();
        ui->upButton->hide();
        return;
    }

    if(current<0||current>=files->size()) {
        return;
    }
    
    if(current/itemsPerPage==(filteredFiles->size()-1)/itemsPerPage) {
        ui->downButton->hide();
    } else {
        ui->downButton->show();
    }

    if (current/itemsPerPage==0) {
        ui->upButton->hide();
    } else {
        ui->upButton->show();	
    }

    this->current=current;
    //buttons->at(current)->setStyleSheet(selectedStyleSheet);
    MediaFile * file=filteredFiles->at(current);
    QString artist = (file->artist=="") ? "Unknown Artist" : file->artist;
    QString title = (file->title=="") ? "Untitled" : file->title;
    QString description =(file->description=="") ? "No Description" : file->description;

    ui->movieName->setText(title+"\n"+artist);
    ui->textDescription->setText(description);

    if(interface->getName() == "Photos") // if in Photos UI, show a preview of the picture
    {
        QPixmap pixmap = QPixmap::fromImage(QImage(file->fileLocation + "/" + file->shortName));
        ui->thumbnail->setPixmap(pixmap.scaled(150,150,Qt::KeepAspectRatioByExpanding));
    }
    else                                // else show the cover art image
    {
        QString mediaID = QString::number(dynamic_cast<MediaFile *>(getCurrentButton()->getItem())->mediaID);

        QSqlQueryModel * result = Querier::getModel("SELECT coverArt FROM MediaFiles WHERE mediaID='"+mediaID+"'");
        QString artURL = result->record(0).value("coverArt").toString();

        if(artURL=="") // if there is no custom art, set the default art
        {
            ui->thumbnail->setPixmap(QPixmap(":/imgs/3F00MediaFile.png").scaled(150,150,Qt::KeepAspectRatio));
        }
        else // else use the custom art
        {
            ui->thumbnail->setPixmap(QPixmap(artURL).scaled(150,150,Qt::KeepAspectRatioByExpanding));
        }
    }
}

void FileSelector::addFile(MediaFile *file) {
    QPushButton * button= new QPushButton(file->shortName);
    files->append(file);
}

void FileSelector::buttonSelected() {
    if(!active) {
        return;
    }
    if(getCurrentButton()==sortByButton) {
        deactivate();
        sortByButton->activate();
    } else {
        MediaFile * mediaFile =(MediaFile *)(getCurrentButton()->getItem());
        //qDebug() <<"file is "<<mediaFile->fileLocation+"/"+mediaFile->shortName;
        if(mediaFile)
        {
            QTest::qWait(125);
            //interface->setMediaFile(mediaFile);
            qDebug() <<"setting files";
            interface->setVolume(KeyControllableMenu::volumeDisplay->getVolume());
            PlayerManager::setPlayer(interface);
            WindowManager::showWidget(player);
            interface->setMediaQueue(filteredFiles,filteredFiles->indexOf(mediaFile));

        }
    }
}

void FileSelector::buttonSelected(Button * button) {
    if(button==nameSort) {
        qDebug() <<"sorting by name";
        qSort(files->begin(),files->end(),sortByName);
        sortByButton->setText(button->text());
        filteredFiles->clear();
        foreach(MediaFile * file, * files) {
            filteredFiles->append(file);
        }
        current=0;
        showFiles(0);
        activate();
    } else if(button==dateSort) {
        qDebug()<<"sorting by date";
        qSort(files->begin(),files->end(),sortByDate);
        sortByButton->setText(button->text());
        filteredFiles->clear();
        foreach(MediaFile * file, * files) {
            filteredFiles->append(file);
        }
        current=0;
        showFiles(0);
        activate();
    } else if(button==favouriteButton) {
        QString mediaID = QString::number(dynamic_cast<MediaFile *>(getCurrentButton()->getItem())->mediaID);
        QSqlQuery query = Querier::getResult("SELECT favourite FROM MediaFiles WHERE mediaID='"+mediaID+"'");
        query.next();
        QString favourite = QString::number(!query.value(0).toInt());
        Querier::getResult("UPDATE MediaFiles SET favourite='"+favourite+"' WHERE mediaID='"+mediaID+"'");
        popup->deactivate();
        this->reloadFiles(playlistName);
        activate();
    } else if (button==addToPlaylistButton) {
        popup->deactivate();
        playlistSelectionDialog->show();
    } else if (button==removeFromPlaylistButton) {
        removeCurrentMediaFromPlaylist();
        this->reloadFiles(playlistName);
        popup->deactivate();
        activate();
    } else if (button==propertiesButton) {
        popup->deactivate();
        propertiesDialog->show(dynamic_cast<MediaFile *>(getCurrentButton()->getItem()));
    } else if(button==coverArtButton) {
        popup->deactivate();
        QDir directory=QDir(qApp->applicationDirPath()); // bring up a file browser
        #if defined(Q_OS_WIN)
            if (directory.dirName().toLower() == "debug" || directory.dirName().toLower() == "release")
                directory.cd("C:");
        #elif defined(Q_OS_MAC)
                directory.cdUp();
                directory.cdUp();
                directory.cdUp();
        #endif

        QString name=QFileDialog::getOpenFileName(this, tr("Open Cover Art Image"), directory.path(), tr("Image Files (*.png *.jpg *.jpeg *.bmp)"));
        if(name.size()>0) // if a valid image was selected
        {
            QString mediaID = QString::number(dynamic_cast<MediaFile *>(getCurrentButton()->getItem())->mediaID); // get the media ID of the media file
            Querier::getResult("UPDATE MediaFiles SET coverArt='"+name+"' WHERE mediaID='"+mediaID+"'"); // store URL of cover art in db
        }
        this->reloadFiles(playlistName); // reload to show the new cover art
        activate();
    } else if (button==cancelButton) {
       popup->deactivate();
       activate();
    }
}

void FileSelector::buttonRightClicked() {
    addAndRemoveButtons();
    if(getCurrentButton()==sortByButton) {
        return;
    }
    MediaFile * mediaFile=dynamic_cast<MediaFile *>(getCurrentButton()->getItem());
    if(!mediaFile) {
        return;
    }
    QSqlQuery query;

    deactivate();

    query = Querier::getResult("SELECT favourite FROM MediaFiles WHERE mediaID='"+QString::number(mediaFile->mediaID)+"'");
    query.next();
    (query.value(0).toInt()) ? favouriteButton->setText("Remove from favourites") : favouriteButton->setText("Add to favourites");

    qDebug()<<"moving popup to x: "<<QString::number(getCurrentButton()->x()+getCurrentButton()->width()+ui->mainLayout->x())<<" y: "<<QString::number(ui->mainLayout->y()+ getCurrentButton()->y());
    displayPopup(popup,30+frameGeometry().x()+getCurrentButton()->frameGeometry().x()+getCurrentButton()->width(),getCurrentButton()->y()+ui->fileLayout->frameGeometry().y()+50);
//  popup->move(getCurrentButton()->x()+getCurrentButton()->width()+ui->mainLayout->x()+20,ui->mainLayout->y()+ getCurrentButton()->y());

    popup->activate();
}

void FileSelector::show() {
    KeyControllableMenu::show();
    activate();
    setVisible(true);
    qDebug()<<"reshowing";
    ui->selector->show();
    qDebug() << size();
}

void FileSelector::keyPressEvent(QKeyEvent *event) {
    qDebug() <<"key pressed in the file selector";
    KeyControllableMenu::keyPressEvent(event);
    //PlayerManager::interpretKeys(event);
    QLabel * input =ui->searchBox;
    if(!isVisible()) {
        return;
    }
    //filter results
    if(event->modifiers()==0&&((event->key()>='A'&&event->key()<='z')||(event->key()>='0'&&event->key()<='9')||event->key()==Qt::Key_Backspace)) {
        if(event->key()==Qt::Key_Backspace) {
            input->setText(input->text().mid(0,input->text().size()-1));
        }
        else {
            input->setText(input->text()+event->text());
            qDebug()<<"text is now: "<<input->text();
        }
        filteredFiles->clear();
        foreach(MediaFile * file, * files) {
            if(file->shortName.toLower().contains(input->text().toLower())) {
                filteredFiles->append(file);
            }
        }
        showFiles(0);
        setCurrent(0);
    }
    else if(KeyBindings::matchesKeys(KeyBindings::downKey,event)||KeyBindings::matchesKeys(KeyBindings::upKey,event)) {
        if(getCurrentButton()&&getCurrentButton()!=sortByButton) {
            if(dynamic_cast<MediaFile *>(getCurrentButton()->getItem())) {
                buttonEntered(getCurrentButton());
            }
        }
        else if(KeyBindings::matchesKeys(KeyBindings::downKey,event)&&getCurrentButton()==sortByButton) {
            emit escapeBottom();
            if(getCurrentButton()==sortByButton) {
                buttonEntered(buttons->last());
            }
        }
    }


}

void FileSelector::on_upButton_clicked()
{    
    if(current/itemsPerPage*itemsPerPage>=itemsPerPage) {
        showFiles(current/itemsPerPage*itemsPerPage-itemsPerPage);
        KeyControllableMenu::buttonEntered(buttons->at(itemsPerPage-1));
    }
}

void FileSelector::on_downButton_clicked()
{
    showFiles(current/itemsPerPage*itemsPerPage+itemsPerPage);
}

void FileSelector::propertiesModified(MediaFile * file) {
    if(file){
        Querier::updateMediaFile(file);
        QString artist = (file->artist=="") ? "Unknown Artist" : file->artist;
        QString title = (file->title=="") ? "Untitled" : file->title;
        QString description =(file->description=="") ? "No Description" : file->description;
        ui->movieName->setText(title+"\n"+artist);
        ui->textDescription->setText(description);
        this->reloadFiles(playlistName);
    }
    activate();
}

void FileSelector::addCurrentMediaToPlaylist(QString * playlistName) {
    if(playlistName) Querier::getResult("INSERT INTO Playlists (playlistName,mediaID) VALUES('"+*playlistName+"','"+QString::number(dynamic_cast<MediaFile *>(getCurrentButton()->getItem())->mediaID)+"')");
    activate();
}

void FileSelector::removeCurrentMediaFromPlaylist(){
    Querier::getResult("DELETE FROM Playlists WHERE mediaID='"+QString::number(dynamic_cast<MediaFile *>(getCurrentButton()->getItem())->mediaID)+"' AND playlistName = '" + playlistName +"'");
}

void FileSelector::hide() {
    KeyControllableMenu::hide();
    popup->hide();
    sortByButton->deactivate();
}

void FileSelector::addAndRemoveButtons() {
    if(playlistName!="")
    {   // when viewing a playlist
        addToPlaylistButton->hide();
        removeFromPlaylistButton->show();
    } else { // when not viewing a playlist
    addToPlaylistButton->show();
    removeFromPlaylistButton->hide();
    }
}
